package com.yanqu.road.server.gameplayer.module.activity.liondance;

import com.yanqu.road.dao.impl.activity.liondance.LionDanceUserApplyDataDaoImpl;
import com.yanqu.road.dao.impl.activity.liondance.UserLionDanceDataDaoImpl;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.args.ValueParamArgs;
import com.yanqu.road.entity.activity.liondance.*;
import com.yanqu.road.entity.activity.liondance.config.LionDanceCardInfo;
import com.yanqu.road.entity.activity.liondance.config.LionDanceCombInfo;
import com.yanqu.road.entity.activity.liondance.config.LionDanceJumpConfigInfo;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.config.goods.OpenGoodsBagResult;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eMessageType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.log.LogLionDanceCardChange;
import com.yanqu.road.entity.log.LogLionDanceJumpEnd;
import com.yanqu.road.entity.log.LogLionDanceUserProcess;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.pb.activity.LionDanceProto;
import com.yanqu.road.pb.rank.RankProto;
import com.yanqu.road.pb.worldmessage.WorldMessageProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.ServerLanguageMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.liondance.LionDanceMakeProcess;
import com.yanqu.road.server.manger.activity.liondance.LionDanceMgr;
import com.yanqu.road.server.manger.config.GoodsBagMgr;
import com.yanqu.road.server.manger.config.GoodsMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.player.WorldMessageMgr;
import com.yanqu.road.server.pb.LionDanceActivityPb;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

public class LionDanceModule extends GeneralModule {

    UserLionDanceData userData;

    AtomicInteger applyId;

    public LionDanceModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        ActivityInfo activityInfo = LionDanceMgr.getActivityInfo();
        if(ActivityMgr.activityInShowTime(activityInfo)) {
            int max = new LionDanceUserApplyDataDaoImpl().getMaxApplyId(activityInfo.getActivityId(), player.getUserId());
            applyId = new AtomicInteger(max);
            userData = new UserLionDanceDataDaoImpl().getUserLionDanceData(activityInfo.getActivityId(), player.getUserId());
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        if(userData != null){
            if(userData.isInsertOption()){
                new UserLionDanceDataDaoImpl().add(userData);
            } else if (userData.isUpdateOption()) {
                new UserLionDanceDataDaoImpl().update(userData);
            }
        }

        return true;
    }

    @Override
    public void afterLogin() {

        if (!SystemOpenMgr.systemOpen(player, eSystemId.LionDanceActivity.getValue())) {
            return;
        }

        int activityId = LionDanceMgr.getActivityId();
        LionDanceMakeProcess makeProcess = LionDanceMgr.getCacheAllMakeNumMap().get(activityId);
        if(makeProcess != null){
            updateAllMakeNum(activityId, makeProcess.getCount(), makeProcess.getProcess());
        }

        syncConfig();

        syncUserData();

    }

    public void syncConfig() {
        LionDanceConfig config = LionDanceMgr.getConfig();
        if (config == null || !ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            return;
        }

        LionDanceProto.LionDanceConfigDataSyncMsg.Builder configSync = LionDanceProto.LionDanceConfigDataSyncMsg.newBuilder();
        configSync.addAllCard(LionDanceActivityPb.buildCardListTemp(config.getCardInfoList(), player.getLanguage()));
        configSync.addAllComb(LionDanceActivityPb.buildCombListTemp(config.getCombInfoList(), player.getLanguage()));
        configSync.addAllJump(LionDanceActivityPb.buildJumpListTemp(config.getJumpConfigInfoList()));

        player.sendPacket(Protocol.U_LION_DANCE_SYNC_CONFIG, configSync);
    }

    public synchronized void initUserData() {
        // 系统未解锁
        if (!SystemOpenMgr.systemOpen(player, eSystemId.LionDanceActivity.getValue())) {
            return;
        }

        // 没有活动
        if (!ActivityMgr.activityInShowTime(LionDanceMgr.getActivityInfo()) || LionDanceMgr.getConfig() == null) {
            return;
        }

        ActivityInfo activityInfo = LionDanceMgr.getActivityInfo();

        // 已经有数据了
        if (userData != null && userData.getActivityId() == activityInfo.getActivityId()) {
            return;
        }

        LionDanceConfig config = LionDanceMgr.getConfig();

        UserLionDanceData tmpUserData = new UserLionDanceData();

        tmpUserData.setActivityId(activityInfo.getActivityId());
        tmpUserData.setUserId(getUserId());
        GameStatus status = initPileData(tmpUserData, config);
        status.setSettle(true);
        tmpUserData.setStatus(status);
        tmpUserData.setInsertOption();

        userData = tmpUserData;
        applyId = new AtomicInteger(0);
    }

    public void syncUserData() {
        LionDanceConfig config = LionDanceMgr.getConfig();
        if (config == null || !ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            return;
        }

        if(SystemOpenMgr.systemOpen(player, eSystemId.LionDanceActivity.getValue())){
            if(userData == null || userData.getActivityId() != LionDanceMgr.getActivityId()){
                initUserData();
            }
        }

        if(userData == null){
            return;
        }

        LionDanceProto.LionDanceUserDataSyncMsg.Builder syncMsg = LionDanceProto.LionDanceUserDataSyncMsg.newBuilder();
        LionDanceProto.LionDanceUserDataTemp.Builder builder = LionDanceActivityPb.buildUserData(userData);
        syncMsg.setUserData(builder);
        player.sendPacket(Protocol.U_LION_DANCE_SYNC_USER_DATA, syncMsg);
    }

    /**
     * 制狮
     */
    public int makeLion(int goodsId, int num) {
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }

        GoodsInfo goodsInfo = GoodsMgr.getGoodsById(goodsId);
        if(goodsInfo == null){
            return GameErrorCode.E_GOODS_NO_EXIST;
        }

        LionDanceConfig config = LionDanceMgr.getConfig();
        if(config == null){
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }

        if(goodsId != config.getConsumeItemId()){
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }

        if(!player.getModule(CurrencyModule.class).removeCurrency(PropertyHelper.parseStringToProperty(goodsId + "=" + num), eLogMoneyType.LionDance, eLogMoneyType.LionDanceMakeLionConsume)){
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }

        //奖励
        Property reward = new Property();
        for (int i = 0; i < num; i++) {
            OpenGoodsBagResult openResult = GoodsBagMgr.getRandomGoods(goodsId);
            reward.addProperty(openResult.getReward());
        }
        player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.LionDance, eLogMoneyType.LionDanceMakeLionReward);

        //进度
        int oldMakeNum = userData.getMakeNum();
        int addProcess = goodsInfo.getParamList().get(0).intValue() * num;
        userData.setProcess(userData.getProcess() + addProcess);

        int add = userData.getProcess() / 1000;
        userData.setProcess(userData.getProcess() - 1000 * add);
        userData.setMakeNum(userData.getMakeNum() + add);
        userData.setTotalUseNum(userData.getTotalUseNum() + num);

        //上传跨服
        LionDanceProto.CrossLionDanceUploadUserMakeNumMsg.Builder uploadMsg = LionDanceProto.CrossLionDanceUploadUserMakeNumMsg.newBuilder();
        uploadMsg.setActivityId(userData.getActivityId());
        uploadMsg.setNum(userData.getMakeNum());
        uploadMsg.setProcess(userData.getProcess());
        uploadMsg.setUserId(userData.getUserId());
        uploadMsg.setNeedSync(oldMakeNum != userData.getMakeNum());
        player.sendPacket(Protocol.C_LION_DANCE_UPLOAD_USER_MAKE_NUM, uploadMsg);

        LionDanceProto.LionDanceMakeRespMsg.Builder respMsg  = LionDanceProto.LionDanceMakeRespMsg.newBuilder().setRet(0);
        respMsg.setReward(PropertyHelper.parsePropertyToString(reward));
        respMsg.setUserData(LionDanceActivityPb.buildUserData(userData));
        player.sendPacket(Protocol.U_LION_DANCE_MAKE_LION, respMsg );

        //日志
        AutoLogMgr.add(new LogLionDanceUserProcess(userData.getActivityId(), userData.getUserId(), num, userData.getTotalUseNum(), userData.getProcess() + 1000 * userData.getMakeNum(),
                PropertyHelper.parsePropertyToString(reward)));

        return 0;
    }

    public int startNew() {
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        if(!userData.getStatus().isSettle()){
            //跳桩未结束
            return GameErrorCode.E_LION_DANCE_GAME_NO_END;
        }

        LionDanceConfig config = LionDanceMgr.getConfig();

        GameStatus status = initPileData(userData, config);
        userData.setStatus(status);


        LionDanceProto.LionDanceStartNewRespMsg.Builder respMsg = LionDanceProto.LionDanceStartNewRespMsg.newBuilder().setRet(0);
        respMsg.setUserData(LionDanceActivityPb.buildUserData(userData));
        player.sendPacket(Protocol.U_LION_DANCE_START_NEW, respMsg);
        return 0;
    }

    private GameStatus initPileData(UserLionDanceData userData, LionDanceConfig config) {
        Random random = new Random();
        List<Pile> result = new ArrayList<>();
        //卡片数
        int itemNum = 0;
        //加成个数
        int addNum = 0;
        int stepNum = 0;
        for (LionDanceJumpConfigInfo passConfigInfo : config.getJumpConfigInfoList()) {
            for (int i = 0; i < passConfigInfo.getPileNum(); i++) {
                Pile pile = new Pile();
                pile.setNum(stepNum++);
                int position = 1 + pile.getNum();

                pile.setGap(passConfigInfo.getGapRangeList().get(0) + random.nextInt(passConfigInfo.getGapRangeList().get(1) - passConfigInfo.getGapRangeList().get(0)));
                if(passConfigInfo.getColorNumList().contains(position)){
                    //彩球桩
                    pile.setType(2);
                }else {
                    //组合桩
                    pile.setType(1);
                    //桩面类型
                    pile.setfType(RandomHelper.getRandomIndexByWeight(passConfigInfo.getFackWeightList(), random) + 1);
                    //柱子类型
                    pile.setcType(RandomHelper.getRandomIndexByWeight(passConfigInfo.getColumnWeightList(), random) + 1);
                    //移动状态
                    pile.setMove(RandomHelper.getRandomIndexByWeight(passConfigInfo.getDynamicWeightList(), random) + 1);
                    //柱子高度
                    pile.setcHigh(RandomHelper.getRandomIndexByWeight(passConfigInfo.getPileHighWeighList(), random) + 1);
                }
                if(passConfigInfo.getAddItemPosition().contains(position)){
                    //加成道具
                    int addition = config.getWeightItem(passConfigInfo.getAddItem(), random);
                    pile.setaId(addition);
                    //收集方位
                    pile.setP(RandomHelper.getRandomIndexByWeight(passConfigInfo.getCollectItemType(), random) + 1);
                    addNum++;
                }
                if(passConfigInfo.getCollectItemPosition().contains(position)){
                    //收集道具
                    int goodsId = config.getWeightItem(passConfigInfo.getCollectItem(), random);
                    pile.setgId(goodsId);
                    //收集方位
                    pile.setP(RandomHelper.getRandomIndexByWeight(passConfigInfo.getCollectItemType(), random) + 1);
                    itemNum++;
                }

                result.add(pile);
            }
        }

        userData.setPileList(result);
        GameStatus status = new GameStatus();
        status.setAllGoodsNum(itemNum);
        status.setAllAddNum(addNum);
        status.setStartTime(DateHelper.getCurrentSecond());
        status.setSettle(false);
        return status;
    }

    /**
     *
     * @param result 结果：0 失败
     * @param power 力度
     * @param step 步骤
     * @param gap 间距
     * @return
     */
    public int jumpNext(int result, int power, int step, int gap) {
        if(result != 0 && result != 1){
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }

        LionDanceConfig config = LionDanceMgr.getConfig();
        if(config == null){
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }

        GameStatus gameStatus = userData.getStatus();
        if(gameStatus.isSettle()){
            return GameErrorCode.E_LION_DANCE_GAME_END;
        }
        if(gameStatus.getStep() != step){
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }

        //跳跃的时间
        gameStatus.setJumpTime(System.currentTimeMillis());

        //（每个跳一跳的积分+制狮进度加成积分）* 收集物加成积分倍数

        //舞狮进度加成积分
        int addScore = LionDanceMgr.getMakeLionAddition(userData.getMakeNum(), userData.getProcess(), config);
        //本次跳跃最后获得
        int getScore = addScore + config.getLIONDANCE_JUMP_SCORE();

        //收集物加倍数
        int addition = getJumpScoreAddition(userData.getStatus());
        //积分
        if(addition > 0){
            getScore = BigDecimal.valueOf(getScore).multiply(BigDecimal.valueOf(addition)).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_UP).intValue();
        }

        //成功才加积分
        if(result == 1) {
            gameStatus.setScore(gameStatus.getScore() + getScore);
            userData.setScore(userData.getScore() + getScore);
        }

        LionDanceMgr.getLogger().info("玩家{}， 跳桩， 在桩{}, step : {}，时间{}", player.getUserId(), gameStatus.getStep(), step, DateHelper.getCurrentDateTimeString(gameStatus.getJumpTime()));
        boolean newMax = false;
        if(result == 0){
            //失败
            gameStatus.setSettle(true);
            if(userData.getMaxScore() < gameStatus.getScore()){
                userData.setMaxScore(gameStatus.getScore());
                newMax = true;
            }
            addCard(userData, gameStatus.getGetNumMap(), config);
        }else {
            gameStatus.setStep(1 + gameStatus.getStep());
            if(gameStatus.getStep() + 1 == userData.getPileList().size()){
                //最后一步
                //结算
                gameStatus.setSettle(true);
                if(userData.getMaxScore() < gameStatus.getScore()){
                    userData.setMaxScore(gameStatus.getScore());
                    newMax = true;
                }
                addCard(userData, gameStatus.getGetNumMap(), config);
            }
        }
        if(gameStatus.isSettle()){
            if(newMax){
                player.notifyListener(eGamePlayerEventType.LionDanceScoreRank.getValue(), new ValueParamArgs(userData.getMaxScore(), ""));
                //取榜单排名
                LionDanceProto.LionDanceActivityRankListReqMsg.Builder rankReq = LionDanceProto.LionDanceActivityRankListReqMsg.newBuilder();
                rankReq.setConditionType(eGamePlayerEventType.LionDanceScoreRank.getValue());
                rankReq.setActivityId(userData.getActivityId());
                RankProto.RankTempMsg.Builder builder = RankProto.RankTempMsg.newBuilder();
                builder.setValue(String.valueOf(userData.getMaxScore()));
                builder.setUserId(userData.getUserId());
                builder.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(UserMgr.getUserBaseInfo(userData.getUserId(), GameServer.getInstance().getServerId())));
                rankReq.setRank(builder);
                player.sendPacket(Protocol.C_LION_DANCE_GET_GET_MY_SCORE_RANK, rankReq);
            }
        }
        //时间校验
        LionDanceProto.LionDanceJumpCurRespMsg.Builder respMsg = LionDanceProto.LionDanceJumpCurRespMsg.newBuilder().setRet(0);
        respMsg.setUserData(LionDanceActivityPb.buildUserData(userData));
        player.sendPacket(Protocol.U_LION_DANCE_JUMP, respMsg);

        if(gameStatus.isSettle()){
            //结束日志
            Property card = new Property();
            for (Map.Entry<Integer, Integer> entry : gameStatus.getGetNumMap().entrySet()) {
                card.addProperty(entry.getKey(), BigInteger.valueOf(entry.getValue()));

                //卡牌日志
                AutoLogMgr.add(new LogLionDanceCardChange(userData.getActivityId(), userData.getUserId(),
                        entry.getKey(), entry.getValue(),
                        1, 0,
                        0, 0, 0));
            }
            Pile pile = userData.getPileList().get(gameStatus.getStep());
            AutoLogMgr.add(new LogLionDanceJumpEnd(userData.getActivityId(), userData.getUserId(),
                    getScore, gameStatus.getGetAddNum(), PropertyHelper.parsePropertyToString(card),
                    gameStatus.getStep(), result == 1, pile.getType(),
                    gameStatus.getScore(),
                    gameStatus.getStartTime(),
                    DateHelper.getCurrentSecond() - gameStatus.getStartTime()));
        }
        //LionDanceMgr.getLogger().info("=================end{}, 排名 {}", player.getUserId(), userData.getMaxRank());
        return 0;
    }

    private int getJumpScoreAddition(GameStatus status) {
        if(status.getAdditionTime() >= DateHelper.getCurrentSecond()){
            return status.getAddition();
        }
        return 0;
    }

    private void addCard(UserLionDanceData userData, Map<Integer, Integer> getNumMap, LionDanceConfig config) {
        for (Map.Entry<Integer, Integer> entry : getNumMap.entrySet()) {
            userData.getCardMap().addProperty(entry.getKey(), BigInteger.valueOf(entry.getValue()));
        }
        userData.setUpdateOption();
        //集卡成就
    }

    /**
     * 跳跃收集道具（加成道具或者卡片）
     */
    public int jumpAddItem(int type, int step, int time) {
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }

        LionDanceConfig config = LionDanceMgr.getConfig();
        if(config == null){
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }

        GameStatus gameStatus = userData.getStatus();
        if(gameStatus.isSettle()){
            return GameErrorCode.E_LION_DANCE_GAME_END;
        }

        if(step < 0 || step > userData.getPileList().size() - 1){
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }

        if(Math.abs(step - gameStatus.getStep()) > 1){
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }

        if(type == 2 && gameStatus.getStepList().contains(step)){
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }

        if(type == 1 && gameStatus.getScoreStepList().contains(step)){
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }

        if(type == 2) {
            gameStatus.getStepList().add(step);
        }else if(type == 1){
            gameStatus.getScoreStepList().add(step);
        }

        Pile pile = userData.getPileList().get(step);


        if(type == 1) {
            //彩桩积分
            if (pile.getType() == 2) {
                int idx = RandomHelper.getRandomIndexByWeight(config.getLIONDANCE_COLOR_WEIGHT(), new Random());
                int score = config.getLIONDANCE_COLOR_REWARD_SCORE().get(idx);
                gameStatus.setScore(score + gameStatus.getScore());
                userData.setScore(score + userData.getScore());
                LionDanceMgr.getLogger().info("玩家{}， 彩桩积分{}， 在桩{}, step : {}", player.getUserId(), score, pile.getNum(), step);
            }
        }

        if(type == 2) {
            if (pile.getgId() > 0) {
                int num = gameStatus.getGetNumMap().getOrDefault(pile.getgId(), 0);
                gameStatus.getGetNumMap().put(pile.getgId(), num + 1);
                gameStatus.setGetNum(1 + gameStatus.getGetNum());
                LionDanceMgr.getLogger().info("玩家{}， 收集道具{}， 在桩{}, step : {}", player.getUserId(), pile.getgId(), pile.getNum(), step);
            } else if (pile.getaId() > 0) {
                gameStatus.setAddition(pile.getaId());
                gameStatus.setAdditionTime(DateHelper.getCurrentSecond() + config.getLIONDANCE_ADD_ITEM_CONTINUED_TIME());
                gameStatus.setGetAddNum(1 + gameStatus.getGetAddNum());
                LionDanceMgr.getLogger().info("玩家{}， 加成道具{}， 在桩{}, step : {}", player.getUserId(), pile.getaId(), pile.getNum(), step);
            }
        }

        LionDanceProto.LionDanceJumpItemAddRespMsg.Builder respMsg = LionDanceProto.LionDanceJumpItemAddRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setUserData(LionDanceActivityPb.buildUserData(userData));
        player.sendPacket(Protocol.U_LION_DANCE_JUMP_ADD_ITEM, respMsg);
        return 0;
    }

    /**
     * 申请卡片
     */
    public int applyCard(int cardId, int way) {
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }

        List<LionDanceUserApplyData> applyDataList = LionDanceMgr.getApplyDataList(player.getUserId());
        LionDanceUserApplyData applyData = findValidApplyData(applyDataList);
        if(applyData != null){
            //当前已有申请
            return GameErrorCode.E_LION_DANCE_APPLY_EXIST;
        }

        LionDanceConfig config = LionDanceMgr.getConfig();
        if(config == null){
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }

        //卡片是否有效
        LionDanceCardInfo cardInfo = config.getCardById(cardId);
        if(cardInfo == null){
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }

        applyData = new LionDanceUserApplyData();
        applyData.setActivityId(userData.getActivityId());
        applyData.setApplyGoodsId(cardId);
        applyData.setApplyTimes(System.currentTimeMillis());
        applyData.setUserId(player.getUserId());
        applyData.setApplyNo(applyId.incrementAndGet());
        applyData.setInsertOption();
        applyData.setFromType(way);
        synchronized (applyDataList) {
            applyDataList.add(applyData);
        }

        //上报跨服
        LionDanceProto.CrossLionDanceUploadApplyMsg.Builder uploadApplyMsg = LionDanceProto.CrossLionDanceUploadApplyMsg.newBuilder();
        uploadApplyMsg.setActivityId(userData.getActivityId());
        uploadApplyMsg.setApplyNo(applyData.getApplyNo());
        uploadApplyMsg.setTime(applyData.getApplyTimes());
        uploadApplyMsg.setCardId(applyData.getApplyGoodsId());
        player.sendPacket(Protocol.C_LION_DANCE_UPLOAD_APPLY_CARD, uploadApplyMsg);

        //聊天窗口
        sendApplyDataChat(applyData, way);

        LionDanceProto.LionDanceApplyCardRespMsg.Builder respMsg = LionDanceProto.LionDanceApplyCardRespMsg.newBuilder().setRet(0);
        for (int i = 0; i < applyDataList.size(); i++) {
            LionDanceUserApplyData applyData1 = applyDataList.get(i);
            respMsg.addApply(LionDanceActivityPb.buildApplyData(applyData1));
        }
        player.sendPacket(Protocol.U_LION_DANCE_APPLY_CARD, respMsg);
        LionDanceMgr.getLogger().info("--------- 玩家 {} 申请卡牌 {}, 编号：{}", player.getUserId(), cardId, applyData.getApplyNo());
        return 0;
    }

    private LionDanceUserApplyData findValidApplyData(List<LionDanceUserApplyData> applyDataList) {
        for (int i = 0; i < applyDataList.size(); i++) {
            LionDanceUserApplyData applyData = applyDataList.get(i);
            if(applyData.getStatus() == 0 || applyData.getStatus() == 2){
                return applyData;
            }
        }
        return null;
    }

    public void sendApplyDataChat(LionDanceUserApplyData applyData, int way) {

        WorldMessageProto.WorldMessageTempMsg.Builder messageBuilder = WorldMessageProto.WorldMessageTempMsg.newBuilder();
        messageBuilder.setContentType(1);
        messageBuilder.setType(way == 2 ? eMessageType.LionDanceApplyHelp.getValue() : eMessageType.LionDanceUnionApplyHelp.getValue());
        List<String> paramsList = new ArrayList<>();
        //content  : serverId|applyNo|applyCardId|applyTime|nickName
        paramsList.add(String.valueOf(GameServer.getInstance().getServerId()));
        paramsList.add(String.valueOf(applyData.getApplyNo()));
        paramsList.add(String.valueOf(applyData.getApplyGoodsId()));
        paramsList.add(String.valueOf(applyData.getApplyTimes()));
        paramsList.add(player.getUserInfo().getNickName());
        LionDanceConfig config = LionDanceMgr.getConfig();
        if(config != null){
            LionDanceCardInfo cardInfo = config.getCardById(applyData.getApplyGoodsId());
            if(cardInfo != null) {
                paramsList.add(ServerLanguageMgr.getContent(cardInfo.getName(), player.getLanguage()));
            }
        }
        messageBuilder.setContent(StringUtils.listToString(paramsList, "@#$"));
        messageBuilder.setActivityId(userData.getActivityId());
        messageBuilder.setSendTime(applyData.getApplyTimes() / 1000);
        messageBuilder.setBanquetId("");
        messageBuilder.setUserId(userData.getUserId());
        UserBaseInfo userBaseInfo = UserMgr.getUserBaseInfo(userData.getUserId(), GameServer.getInstance().getServerId());
        messageBuilder.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
        //1：商会频道；2：活动频道
        if(way == 2){
            WorldMessageMgr.sendCrossActivityChat(messageBuilder);
        }else if(way == 1){
            WorldMessageMgr.sendUnionChat(player, messageBuilder);
        }
    }

    /**
     * 我的申请历史
     */
    public int myApplyList() {
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        LionDanceProto.LionDanceUserApplyListRespMsg.Builder respMsg = LionDanceProto.LionDanceUserApplyListRespMsg.newBuilder().setRet(0);
        respMsg.addAllApply(LionDanceActivityPb.buildApplyDataList(LionDanceMgr.getApplyDataList(player.getUserId())));
        player.sendPacket(Protocol.U_LION_DANCE_MY_APPLY_LIST, respMsg);
        return 0;
    }

    /**
     * 领取卡片
     */
    public int getCardGift(int applyNo) {
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }

        LionDanceConfig config = LionDanceMgr.getConfig();

        List<LionDanceUserApplyData> list = LionDanceMgr.getApplyDataList(player.getUserId());
        LionDanceUserApplyData applyData = LionDanceMgr.find(list, applyNo);
        if(applyData == null){
            return GameErrorCode.E_LION_DANCE_APPLY_NO_VALID;
        }

        if(applyData.getStatus() != 2){
            return GameErrorCode.E_LION_DANCE_APPLY_NO_VALID;
        }

        applyData.setStatus(3);

        int cardId = applyData.getApplyGoodsId();

        userData.getCardMap().addProperty(cardId, BigInteger.ONE);
        userData.setUpdateOption();

        LionDanceProto.LionDanceGetFriendGiftRespMsg.Builder respMsg = LionDanceProto.LionDanceGetFriendGiftRespMsg.newBuilder().setRet(0);
        respMsg.setReward(cardId + "=1");
        respMsg.setUserData(LionDanceActivityPb.buildUserData(userData));
        respMsg.addAllApply(LionDanceActivityPb.buildApplyDataList(LionDanceMgr.getApplyDataList(player.getUserId())));
        player.sendPacket(Protocol.U_LION_DANCE_GET_FRIEND_GIFT, respMsg);

        //卡牌日志(他人赠送)
        AutoLogMgr.add(new LogLionDanceCardChange(userData.getActivityId(), userData.getUserId(),
                applyData.getApplyGoodsId(), 1,
                1, 1,
                0, 0, applyData.getFriendId()));
        return 0;
    }

    /**
     * 取消卡片申请（协助）
     */
    public int cancelApply(int applyNo) {
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }

        List<LionDanceUserApplyData> applyDataList = LionDanceMgr.getApplyDataList(player.getUserId());
        synchronized (applyDataList){
            LionDanceUserApplyData applyData = LionDanceMgr.find(applyDataList, applyNo);
            if(applyData == null){
                return GameErrorCode.E_LION_DANCE_APPLY_NO_VALID;
            }
            LionDanceMgr.checkApplyDataTimeout(applyData);
            if(applyData.getStatus() != 0){
                return GameErrorCode.E_LION_DANCE_APPLY_NO_VALID;
            }
            applyData.setStatus(4);
        }
        //上跨服取消
        LionDanceProto.CrossLionDanceCancelApplyCardReqMsg.Builder crossMsg = LionDanceProto.CrossLionDanceCancelApplyCardReqMsg.newBuilder();
        crossMsg.setActivityId(userData.getActivityId());
        crossMsg.setApplyNo(applyNo);
        crossMsg.setApplyUserId(player.getUserId());
        player.sendPacket(Protocol.C_LION_DANCE_CANCEL_APPLY_CARD, crossMsg);

        LionDanceProto.LionDanceCancelApplyCardRespMsg.Builder respMsg = LionDanceProto.LionDanceCancelApplyCardRespMsg.newBuilder().setRet(0);
        respMsg.addAllApply(LionDanceActivityPb.buildApplyDataList(LionDanceMgr.getApplyDataList(player.getUserId())));
        player.sendPacket(Protocol.U_LION_DANCE_CANCEL_APPLY, respMsg);
        return 0;
    }

    /**
     * 更新全服进度
     */
    public void updateAllMakeNum(int activityId, long count, int process) {
        if(userData == null){
            return;
        }
        if(userData.getActivityId() == activityId){
            player.notifyListener(eGamePlayerEventType.LionDanceMakeLionProcess.getValue(), count);
            LionDanceProto.LionDanceMakeProcessSync.Builder sync = LionDanceProto.LionDanceMakeProcessSync.newBuilder();
            sync.setCount(count);
            sync.setProcess(process);
            player.sendPacket(Protocol.U_LION_DANCE_SYNC_MAKE_PROCESS, sync);
        }
    }

    /**
     * 赠送卡片（本服）
     */
    public int giveGift(long toUserId, int applyNo, int cardId) {
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }

        int ownNum = userData.getCardMap().getCountByGoodsId(cardId).intValue();
        if(ownNum < 1){
            return GameErrorCode.E_LION_DANCE_CARD_NO_ENOUGH;
        }

        UserBaseInfo userBaseInfo = UserMgr.getUserBaseInfo(player.getUserId(), GameServer.getInstance().getServerId());
        int ret = LionDanceMgr.giveCard(player.getUserId(), toUserId, applyNo, cardId, userBaseInfo);
        if(ret != 0){
            return ret;
        }

        //扣除卡片
        userData.getCardMap().removeProperty(cardId, BigInteger.ONE);
        userData.setUpdateOption();

        //上跨服更新数据
        LionDanceProto.CrossLionDanceCancelApplyCardReqMsg.Builder crossMsg = LionDanceProto.CrossLionDanceCancelApplyCardReqMsg.newBuilder();
        crossMsg.setActivityId(userData.getActivityId());
        crossMsg.setApplyNo(applyNo);
        crossMsg.setApplyUserId(toUserId);
        player.sendPacket(Protocol.C_LION_DANCE_CANCEL_APPLY_CARD, crossMsg);

        player.sendPacket(Protocol.U_LION_DANCE_GIVE_FRIEND, LionDanceProto.LionDanceApplyHandleRespMsg.newBuilder().setRet(ret));

        syncUserData();

        //卡牌日志(赠送他人)
        AutoLogMgr.add(new LogLionDanceCardChange(userData.getActivityId(), userData.getUserId(),
                cardId, 1,
                0, 2,
                0, toUserId, 0));
        return 0;
    }

    /**
     * 他人申请列表
     */
    public int listOtherUserApply(int pageNo, int pageSize) {
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        if(pageSize == 0){
            pageSize = 20;
        }
        LionDanceProto.CrossLionDanceFriendApplyListReqMsg.Builder crossReq = LionDanceProto.CrossLionDanceFriendApplyListReqMsg.newBuilder();
        crossReq.setActivityId(LionDanceMgr.getActivityId());
        crossReq.setPageNo(pageNo);
        crossReq.setPageSize(pageSize);
        player.sendPacket(Protocol.C_LION_DANCE_LIST_APPLY_CARD, crossReq);
        return 0;
    }

    /**
     * 获取组合奖励
     */
    public int getCombReward(int combId) {
        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }

        LionDanceConfig config = LionDanceMgr.getConfig();
        if(config == null){
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }

        LionDanceCombInfo combInfo = config.getLionDanceCombInfo(combId);
        if(combInfo == null){
            return GameErrorCode.E_REQUEST_ARGUMENT_ERROR;
        }

        if(userData.getCombMap().containsKey(combId)){
            return GameErrorCode.E_LION_DANCE_HAD_GET_REWARD;
        }

        for (Map.Entry<Integer, BigInteger> entry : combInfo.getElement().getGoods().entrySet()) {
            if(userData.getCardMap().getCountByGoodsId(entry.getKey()).compareTo(entry.getValue())  < 0){
                return GameErrorCode.E_LION_DANCE_CARD_NO_ENOUGH;
            }
        }

        int times = userData.getCombMap().getOrDefault(combId, 0);
        userData.getCombMap().put(combId, times + 1);

        //扣卡牌
        for (Map.Entry<Integer, BigInteger> entry : combInfo.getElement().getGoods().entrySet()) {
            userData.getCardMap().removeProperty(entry.getKey(), entry.getValue());
        }
        userData.setUpdateOption();
        String reward = combInfo.getRewards();
        player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.LionDance, eLogMoneyType.LionDanceCardCombReward);

        LionDanceProto.LionDanceGetCardCombRewardRespMsg.Builder respMsg = LionDanceProto.LionDanceGetCardCombRewardRespMsg.newBuilder().setRet(0);
        respMsg.setReward(reward);
        respMsg.setUserData(LionDanceActivityPb.buildUserData(userData));
        player.sendPacket(Protocol.U_LION_DANCE_GET_COMB_REWARD, respMsg);

        //卡牌日志(组合消耗)
        AutoLogMgr.add(new LogLionDanceCardChange(userData.getActivityId(), userData.getUserId(),
                0, 0,
                0, 3,
                combId, 0, 0));

        return 0;
    }


    public UserLionDanceData getUserData() {
        return userData;
    }

    public int crossGiveGift(long serverId, long toUserId, int applyNo, int cardId) {
        LionDanceProto.CrossLionDanceApplyHandleReqMsg.Builder crossReq = LionDanceProto.CrossLionDanceApplyHandleReqMsg.newBuilder();
        crossReq.setApplyNo(applyNo);

        if(userData == null){
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }

        LionDanceConfig config = LionDanceMgr.getConfig();
        if(config == null){
            return GameErrorCode.E_ACTIVITY_OVER_TIME;
        }

        int ownNum = userData.getCardMap().getCountByGoodsId(cardId).intValue();
        if(ownNum < 1){
            return GameErrorCode.E_LION_DANCE_CARD_NO_ENOUGH;
        }

        //预扣，到对方区服，赠送
        userData.getCardMap().removeProperty(cardId, BigInteger.ONE);
        userData.setUpdateOption();
        LionDanceMgr.getLogger().info("玩家 {} 赠送卡牌  {} 给好友 {}，applyNo ：{}", player.getUserId(), cardId, toUserId, applyNo);

        crossReq.setActivityId(userData.getActivityId());
        crossReq.setToServerId(serverId);
        crossReq.setApplyNo(applyNo);
        crossReq.setCardId(cardId);
        crossReq.setToUserId(toUserId);
        crossReq.setFromUserId(player.getUserId());
        crossReq.setFromServerId(GameServer.getInstance().getServerId());
        UserBaseInfo userBaseInfo = UserMgr.getUserBaseInfo(player.getUserId(), GameServer.getInstance().getServerId());
        crossReq.setBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
        player.sendPacket(Protocol.C_LION_DANCE_GIVE_APPLY_CARD, crossReq);

        //卡牌日志(赠送他人)
        AutoLogMgr.add(new LogLionDanceCardChange(userData.getActivityId(), userData.getUserId(),
                cardId, 1,
                0, 2,
                0, toUserId, 0));
        return 0;
    }

    public void giveBackFromCross(int ret, long toUserId, int cardId, int applyNo) {
        if(ret != 0){
            //归还道具
            if(userData != null){
                userData.getCardMap().addProperty(cardId, BigInteger.ONE);
                userData.setUpdateOption();

                //卡牌日志(赠送他人失败，进行规范)
                AutoLogMgr.add(new LogLionDanceCardChange(userData.getActivityId(), userData.getUserId(),
                        cardId, 1,
                        1, 4,
                        0, toUserId, 0));
            }
        }
        syncUserData();
        player.sendPacket(Protocol.U_LION_DANCE_GIVE_FRIEND, LionDanceProto.LionDanceApplyHandleRespMsg.newBuilder().setRet(ret));
    }

    public void setMyMaxRank(int myRank) {
        if(userData != null){
            userData.setMaxRank(myRank);
            //LionDanceMgr.getLogger().info("================={}, 排名 {}", player.getUserId(), myRank);
        }
    }
}
